package ofdinv

import (
	"errors"
	"fmt"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

// VATParser 增值税发票解析器
type VATParser struct {
	ofdReader *OFDReader
}

// NewVATParser 创建新的增值税发票解析器
func NewVATParser(reader *OFDReader) *VATParser {
	return &VATParser{
		ofdReader: reader,
	}
}

// Parse 解析增值税发票
func (p *VATParser) Parse() (*InvoiceInfo, error) {
	// 1. 解析文档结构
	document, err := p.ofdReader.ParseDocument()
	if err != nil {
		return nil, fmt.Errorf("解析文档结构失败: %v", err)
	}

	// 2. 解析 CustomTag.xml
	customTagRoot, err := p.parseCustomTag(document)
	if err != nil {
		return nil, fmt.Errorf("解析CustomTag.xml失败: %v", err)
	}

	// 3. 获取页面字段映射
	pageMappings := customTagRoot.GetPageFieldMappings()
	if len(pageMappings) == 0 {
		return nil, fmt.Errorf("未找到有效的页面字段映射")
	}

	// 4. 并发处理每个页面
	invoiceInfo, err := p.parsePagesConcurrently(document, pageMappings)
	if err != nil {
		return nil, fmt.Errorf("并发解析页面失败: %v", err)
	}

	return invoiceInfo, nil
}

// PageInvoiceInfo 表示单个页面的发票信息
type PageInvoiceInfo struct {
	PageRef            int // 页面引用ID，用于排序
	InvoiceNumber      string
	InvoiceDate        string
	BuyerName          string
	BuyerTaxID         string
	SellerName         string
	SellerTaxID        string
	TotalAmount        string
	TotalTax           string
	TotalAmountWithTax string
	Drawer             string
	Note               string
	Items              []VATItem
}

// // parseDocument 解析文档结构
// func (p *VATParser) parseDocument() (*Document, error) {
// 	var document Document
// 	err := p.ofdReader.ReadXMLFile("Doc_0/Document.xml", &document)
// 	if err != nil {
// 		return nil, fmt.Errorf("读取Document.xml失败: %v", err)
// 	}
// 	return &document, nil
// }

// parseCustomTag 解析 CustomTag.xml
func (p *VATParser) parseCustomTag(doc *Document) (*CustomTagRoot, error) {
	var customTagRoot CustomTagRoot
	var customTagsRoot CustomTagsRoot
	CustomTagsPath := filepath.Join("Doc_0", doc.CustomTags)
	err := p.ofdReader.ReadXMLFile(CustomTagsPath, &customTagsRoot)
	if err != nil {
		return nil, fmt.Errorf("读取CustomTag.xml失败: %v", err)
	}
	for _, root := range customTagsRoot.CustomTag {
		if root.TypeID == "root" {
			rootPath := filepath.Join("Doc_0", "Tags", root.FileLoc)
			err := p.ofdReader.ReadXMLFile(rootPath, &customTagRoot)
			if err != nil {
				return nil, fmt.Errorf("读取CustomTag.xml失败: %v", err)
			}
			return &customTagRoot, nil
		}
	}
	return &customTagRoot, errors.New("读取CustomTag.xml失败")
}

// parsePagesConcurrently 并发解析所有页面
func (p *VATParser) parsePagesConcurrently(document *Document, pageMappings []*FieldMappings) (*InvoiceInfo, error) {
	var wg sync.WaitGroup
	results := make(chan *PageInvoiceInfo, len(pageMappings))
	errors := make(chan error, len(pageMappings))

	// 为每个页面启动 goroutine
	for _, mappings := range pageMappings {
		wg.Add(1)
		go func(mappings *FieldMappings) {
			defer wg.Done()
			pageInfo, err := p.parseSinglePage(document, mappings)
			if err != nil {
				errors <- err
				return
			}
			results <- pageInfo
		}(mappings)
	}

	wg.Wait()
	close(results)
	close(errors)

	// 处理错误
	if len(errors) > 0 {
		return nil, <-errors
	}

	// 合并所有页面信息
	return p.mergePageInfos(results), nil
}

// parseSinglePage 解析单个页面
func (p *VATParser) parseSinglePage(document *Document, mappings *FieldMappings) (*PageInvoiceInfo, error) {
	// 1. 获取页面路径
	pageRef := mappings.InvoiceNo.PageRef
	pagePath, err := document.Pages.GetPagePath(pageRef)
	if err != nil {
		return nil, fmt.Errorf("获取页面路径失败 (页面引用 %d): %v", pageRef, err)
	}
	pagePath = filepath.Join("Doc_0", pagePath)

	// 2. 加载页面内容
	var page Page
	err = p.ofdReader.ReadXMLFile(pagePath, &page)
	if err != nil {
		return nil, fmt.Errorf("读取页面内容失败 (路径 %s): %v", pagePath, err)
	}

	// 3. 获取所有文本对象
	textObjects := page.GetAllTextObject()
	textMap := p.buildTextMap(textObjects)

	// 4. 提取字段文本
	pageInfo := &PageInvoiceInfo{
		PageRef: pageRef, // 设置页面引用ID
	}

	// 基础字段
	pageInfo.InvoiceNumber = p.extractFieldText(textMap, mappings.InvoiceNo)
	pageInfo.InvoiceDate = p.extractFieldText(textMap, mappings.IssueDate)
	pageInfo.BuyerName = p.extractFieldText(textMap, mappings.BuyerName)
	pageInfo.BuyerTaxID = p.extractFieldText(textMap, mappings.BuyerTaxID)
	pageInfo.SellerName = p.extractFieldText(textMap, mappings.SellerName)
	pageInfo.SellerTaxID = p.extractFieldText(textMap, mappings.SellerTaxID)
	pageInfo.TotalAmount = p.extractFieldText(textMap, mappings.TaxExclusiveTotalAmount)
	pageInfo.TotalTax = p.extractFieldText(textMap, mappings.TaxTotalAmount)
	pageInfo.TotalAmountWithTax = p.extractFieldText(textMap, mappings.TaxInclusiveTotalAmount)
	pageInfo.Drawer = p.extractFieldText(textMap, mappings.InvoiceClerk)
	pageInfo.Note = p.extractFieldText(textMap, mappings.Note)

	// 商品信息
	for _, goodsMapping := range mappings.GoodsInfos {
		item := p.parseGoodsItem(textMap, goodsMapping)
		pageInfo.Items = append(pageInfo.Items, item)
	}

	return pageInfo, nil
}

// buildTextMap 构建文本对象映射表
func (p *VATParser) buildTextMap(textObjects []TextObject) map[string]string {
	textMap := make(map[string]string)
	for _, obj := range textObjects {
		// 将ID转换为字符串作为键，使用TextCode.Text作为值
		textMap[fmt.Sprintf("%d", obj.ID)] = obj.TextCode.Text
	}
	return textMap
}

// extractFieldText 提取字段文本
func (p *VATParser) extractFieldText(textMap map[string]string, mapping IDMapping) string {
	var texts []string
	for _, objectID := range mapping.ObjectIDs {
		if text, exists := textMap[objectID]; exists {
			texts = append(texts, text)
		}
	}
	return strings.Join(texts, " ")
}

// parseGoodsItem 解析商品项
func (p *VATParser) parseGoodsItem(textMap map[string]string, mapping GoodsInfoMapping) VATItem {
	item := VATItem{}
	item.Name = p.extractFieldText(textMap, mapping.Item)
	item.Spec = p.extractFieldText(textMap, mapping.Specification)
	item.Unit = p.extractFieldText(textMap, mapping.MeasurementDimension)
	item.TaxRate = p.extractFieldText(textMap, mapping.TaxScheme)

	// 数字字段解析
	quantityText := p.extractFieldText(textMap, mapping.Quantity)
	item.Quantity = p.parseFloat(quantityText)

	priceText := p.extractFieldText(textMap, mapping.Price)
	item.UnitPrice = p.parseFloat(priceText)

	amountText := p.extractFieldText(textMap, mapping.Amount)
	item.Amount = p.parseFloat(amountText)

	taxAmountText := p.extractFieldText(textMap, mapping.TaxAmount)
	item.TaxAmount = p.parseFloat(taxAmountText)

	return item
}

// mergePageInfos 合并多个页面信息
func (p *VATParser) mergePageInfos(results chan *PageInvoiceInfo) *InvoiceInfo {
	finalInfo := &InvoiceInfo{
		Type:  InvoiceTypeVAT,
		Items: []VATItem{},
	}

	// 收集所有页面信息
	var pages []*PageInvoiceInfo
	for pageInfo := range results {
		pages = append(pages, pageInfo)
	}

	// 按页面引用ID排序
	for i := 0; i < len(pages)-1; i++ {
		for j := i + 1; j < len(pages); j++ {
			if pages[i].PageRef > pages[j].PageRef {
				pages[i], pages[j] = pages[j], pages[i]
			}
		}
	}

	// 合并基础字段（以最后一个非空值为准）
	for _, pageInfo := range pages {
		if pageInfo.InvoiceNumber != "" {
			finalInfo.InvoiceNumber = pageInfo.InvoiceNumber
		}
		if pageInfo.InvoiceDate != "" {
			finalInfo.InvoiceDate = pageInfo.InvoiceDate
		}
		if pageInfo.BuyerName != "" {
			finalInfo.BuyerName = pageInfo.BuyerName
		}
		if pageInfo.BuyerTaxID != "" {
			finalInfo.BuyerTaxID = pageInfo.BuyerTaxID
		}
		if pageInfo.SellerName != "" {
			finalInfo.SellerName = pageInfo.SellerName
		}
		if pageInfo.SellerTaxID != "" {
			finalInfo.SellerTaxID = pageInfo.SellerTaxID
		}
		if pageInfo.TotalAmount != "" {
			finalInfo.TotalAmount = pageInfo.TotalAmount
		}
		if pageInfo.TotalTax != "" {
			finalInfo.TotalTax = pageInfo.TotalTax
		}
		if pageInfo.TotalAmountWithTax != "" {
			finalInfo.TotalAmountWithTax = pageInfo.TotalAmountWithTax
		}
		if pageInfo.Drawer != "" {
			finalInfo.Drawer = pageInfo.Drawer
		}
		if pageInfo.Note != "" {
			finalInfo.Note = pageInfo.Note
		}
	}

	// 合并商品信息（应用跨行商品合并逻辑）
	finalInfo.Items = p.mergeCrossLineItems(pages)

	return finalInfo
}

// isCrossLineItem 检测是否为跨行商品
// 跨行商品：有项目名称或规格型号，但没有数量、单价、金额、税额等关键数值信息
func (p *VATParser) isCrossLineItem(item *VATItem) bool {
	return (item.Name != "" || item.Spec != "") &&
		item.Quantity == 0 &&
		item.UnitPrice == 0 &&
		item.Amount == 0 &&
		item.TaxAmount == 0
}

// mergeCrossLineItems 合并跨行商品信息
// 基于GoodsInfos结构的精确合并规则：
//  1. 跨页合并：非第一页的第一个GoodsInfos如果是跨行商品，与上一页最后一个GoodsInfos合并
//  2. 同页合并：同一页面内的跨行商品，与同页面前一个有效GoodsInfos合并
func (p *VATParser) mergeCrossLineItems(pages []*PageInvoiceInfo) []VATItem {
	var mergedItems []VATItem

	for pageIndex, page := range pages {
		var pageItems []VATItem

		// 处理每个GoodsInfos（商品行）
		for goodsIndex := 0; goodsIndex < len(page.Items); goodsIndex++ {
			currentItem := page.Items[goodsIndex]

			// 检查是否为跨行商品
			if p.isCrossLineItem(&currentItem) {
				// 跨页合并：非第一页的第一个GoodsInfos
				if pageIndex > 0 && goodsIndex == 0 {
					// 与上一页最后一个GoodsInfos合并
					if len(mergedItems) > 0 {
						lastItem := &mergedItems[len(mergedItems)-1]
						lastItem.Name += currentItem.Name
						lastItem.Spec += currentItem.Spec
						continue
					}
				}

				// 同页合并：同一页面内的跨行商品
				if goodsIndex > 0 {
					// 检查前一个GoodsInfos是否是有效数据行
					prevItem := &page.Items[goodsIndex-1]
					if !p.isCrossLineItem(prevItem) {
						// 与前一个有效GoodsInfos合并
						prevItem.Name += currentItem.Name
						prevItem.Spec += currentItem.Spec
						continue
					}
				}
			}

			// 正常GoodsInfos，直接添加到当前页面
			pageItems = append(pageItems, currentItem)
		}

		// 将当前页面的GoodsInfos添加到最终结果
		mergedItems = append(mergedItems, pageItems...)
	}

	return mergedItems
}

// parseFloat 解析浮点数，处理可能的货币符号和逗号
func (p *VATParser) parseFloat(text string) float64 {
	// 移除可能的货币符号和空格
	text = strings.TrimSpace(text)
	text = strings.ReplaceAll(text, "¥", "")
	text = strings.ReplaceAll(text, "￥", "")
	text = strings.ReplaceAll(text, ",", "")
	text = strings.ReplaceAll(text, " ", "")

	// 如果为空字符串，返回0
	if text == "" {
		return 0
	}

	// 解析为浮点数
	result, err := strconv.ParseFloat(text, 64)
	if err != nil {
		return 0
	}
	return result
}
